/********************************************
 * Joe Helgeson
 * CS362 Assignment 3
 * Unit tests for card-specific functions
 *
 * cardtest3.c - tests great_hall
 * (gives +1 card, +1 axn, +1 estate)
 *******************************************/

#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

// set NOISY_TEST to 0 to remove printfs from output
#define NOISY_TEST 1

//enabling debugging messages to appear
//#ifdef DEBUG
//#undef DEBUG
//#endif
//#define DEBUG 1

void testIt(struct gameState* tState);

///////////////////////////////////////
int main(int argc, char const** argv) {
	struct gameState* tState = malloc(sizeof(struct gameState));
	testIt(tState);
	free(tState);
	return 0;
}

///////////////////////////////////////
void testIt(struct gameState* tState) {

/* personal notes (ignore): 
 int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, struct gameState *state)
 int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus)
*/

	//general initial game setup
	srand(time(NULL));
	int numPlayers = 2;
	int kingdomCards[10];
	int i;
	for (i=0; i<10; i++){
		kingdomCards[i] = i+10;		//offset by 10 to be sure great_hall is covered in kingdom cards in play
	}
	int randomSeed = rand() % 100; //arbitrary number for various functions (usually set by user on cmd line with playdom)
	
	int t; //test number
	for (t=0; t<50; t++) {

		//initialize game (but doesn't create a discard pile)
		int res1 = initializeGame(numPlayers, kingdomCards, randomSeed, tState);
		assert(res1 == 0);

		//specific setup for card under test
		int player = 0;
		int handPos = 0;
		int card = great_hall;
		int choice1 = 0; //irrelevant for this card
		int choice2 = 0; //irrelevant for this card
		int choice3 = 0; //irrelevant for this card
		int bonusval = 0; //irrelevant for this card
		int* bonus = &bonusval; //irrelevant for this card

		//randomly set hand size and save a backup
		tState->handCount[player] = rand() % 10 + 1; //need at least 1 card to play
		int origHandSize = tState->handCount[player];  //backup hand count to compare against
		printf("Testing card %d with a hand of %d cards, ", card, origHandSize);

		//randomly set number of actions and save a backup
		int origNumActions = rand() % 10 + 1; //need at least 1 action to play the card
		tState->numActions = origNumActions;
		printf("%d actions... \n", origNumActions);
		
		//make a discard pile and count the estates in it
		int dpc = rand() % 100; //100 should be plenty for a discard-pile-count max
		tState->discardCount[player] = 0; //start with empty discard pile
		int dPos;  //discard pile position
		int numEstOrig = 0;  //number of estates in original discard pile created
		for (dPos = 0; dPos < dpc; dPos++) {
			int ndpc = rand() % 26; //generate next-discard-pile-card from the 27 types available
			tState->discard[player][dPos] = ndpc; 
			if (tState->discard[player][dPos] == estate) {
				numEstOrig++;
			}
			tState->discardCount[player]++;
		}

		//test card #16 (great_hall)
		int res2 = cardEffect(card, choice1, choice2, choice3, tState, handPos, bonus);
		assert(res2 == 0);

		//post-play tests
		//check for no change in number of cards in hand (+1 card minus great_hall discarded)
		if (tState->handCount[player] != origHandSize) {
			printf("Test failed, Great Hall did not add a card to hand\n");
			printf("Player handCount = %d, origHandSize = %d\n", tState->handCount[player], origHandSize);
			return;
		} 
		else {
			printf("Test passed, Great Hall added a card to hand\n");
		}

		//check for +1 actions (action not subtracted by cardEffect)
		if (tState->numActions != (origNumActions + 1)) {
			printf("Test failed, Great Hall did not add an action\n");
			printf("Player numActions = %d, origNumActions = %d\n", tState->numActions, origNumActions);
			return;
		} 
		else {
			printf("Test passed, Great Hall added an action\n");
		}

/* removing the following test for +1 estate, because I had misunderstood that the
 * great_hall card is deemed the estate itself, and the Victory card count is 
 * handled by other functions (and this is supposed to be a unit test).

		//check for +1 estate in discard pile
		int numEstAfter = 0; //number of estates after card is used (initialized)
		for (dPos = 0; dPos < tState->discardCount[player]; dPos++) {
			if (tState->discard[player][dPos] == estate) {
				numEstAfter++;
			}
		}
		if (numEstAfter != (numEstOrig + 1)) {
			printf("Test failed, Great Hall did not add an estate\n");
			printf("Number of estates after = %d, number of estates originally = %d\n", numEstAfter, numEstOrig);
			return;
		}
		else {
			printf("Test passed, Great Hall added an estate\n");
		}
 */

	}
	printf("Great Hall unit test passed.\n");
	return;
}

